﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using Blade.Compilation;
using Blade.Metadata;

namespace Blade {
	public sealed partial class Runtime : IServiceContainer {
		public static Runtime Current {
			get { return m_Current; }
		}

		[ThreadStatic]
		private static Runtime m_Current;

		ServiceContainer services = new ServiceContainer();

		public Runtime() {
			if (m_Current != null)
				throw new NotSupportedException();
			m_Current = this;
			services.AddService<Runtime>(this);
			services.AddServiceAlias<IMetadataPlatform, PlatformBase>(ServiceType.Default);
		}

		public ReadOnlyCollection<RuntimeAppDomain> AppDomains { get { return m_AppDomains.AsReadOnly(); } }
		private List<RuntimeAppDomain> m_AppDomains = new List<RuntimeAppDomain>();

		public RuntimeAppDomain CreateAppDomain() {
			var domain = new RuntimeAppDomain();
			m_AppDomains.Add(domain);
			return domain;
		}

		#region IServiceContainer Members

		public void AddService<T>(Func<IServiceContainer, T> callback, ServiceType kind) {
			services.AddService<T>(callback, kind);
		}
		public void AddServiceAlias<TService, TAlias>(ServiceType kind)
			where TAlias : TService {
			services.AddServiceAlias<TService, TAlias>(kind);
		}

		public void RemoveService<T>() {
			services.RemoveService<T>();
		}

		public bool ContainsService<T>() {
			return services.ContainsService<T>();
		}

		public bool TryGetService<T>(out T value) {
			return services.TryGetService<T>(out value);
		}

		#endregion
	}
}
